package com.atguigu.lease.common.handler;

import com.atguigu.lease.common.exception.StgyException;
import com.atguigu.lease.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @Author GQS @Date 2024/8/30/9:25 @Description
 */
// 该类用于全局处理异常，当控制器中的操作抛出异常时，会在这里进行统一处理并返回相应的响应
// 使用 @RestControllerAdvice 注解标记该类，表示这是一个处理 REST 控制器异常的类，将返回 JSON 数据
// 同时使用了 Log4j2 进行日志记录
@RestControllerAdvice
@Slf4j
public class StgyGlobalExceptionHandler {

    // 处理所有 Exception 类型的异常，这是最高级别的异常处理器
    // 当控制器中的操作抛出任何异常时，这个方法都会被触发
    // 使用 @ExceptionHandler 注解指定处理的异常类型，这里处理所有继承自 Exception 的异常
    @ExceptionHandler(value = Exception.class)
    public Result exception(Exception e){
        // 记录异常的堆栈信息到日志，这对于后续分析异常原因非常有帮助
        // 异常的堆栈信息包含了异常发生的原因、在哪个类中、哪一行等信息
        log.error(ExceptionUtils.getStackTrace(e));
        // 返回一个表示失败的结果对象，具体实现取决于 Result 类的定义
        // 这里告诉调用者，发生了无法明确处理的异常
        return Result.fail();
    }

    // 专门处理自定义的 StgyException 异常，相比处理所有异常，这个更具体
    // 当控制器中的操作抛出自定义的 StgyException 异常时，这个方法会被触发
    // 使用 @ExceptionHandler 注解指定处理 StgyException 类型的异常
    @ExceptionHandler(value = StgyException.class)
    public Result exception(StgyException e){
        // 检查 StgyException 是否包装了其他原始异常，如果有的话，打印原始异常的堆栈信息
        if(e.getThrowable()!=null){
            // 获取并记录真实异常（如果是包装过的）的堆栈信息
            log.error(ExceptionUtils.getStackTrace(e.getThrowable()));
        }
        // 根据 StgyException 中的信息构建并返回一个结果对象
        // 这里返回的结果包含了异常的代码、消息，且标记为失败（false），无额外数据（null）
        return Result.build(e.getCode(),e.getMessage(),false , null);
    }
}


